package com.koron.order.change.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.koron.bean.query.PageQuery;
import com.koron.common.core.util.CodeTools;
import com.koron.order.change.bean.convertor.OrderChangeConvertor;
import com.koron.order.change.bean.dto.OrderChangeDto;
import com.koron.order.change.bean.po.OrderChangePo;
import com.koron.order.change.bean.po.OrderChangeStatus;
import com.koron.order.change.bean.query.OrderChangeQuery;
import com.koron.order.change.bean.vo.OrderChangeDetailVo;
import com.koron.order.change.bean.vo.OrderChangeVo;
import com.koron.order.change.mapper.OrderChangeMapper;
import com.koron.order.change.service.OrderChangeService;
import com.koron.order.change.util.ThreadLocalOrderChange;
import com.koron.order.common.bean.base.OrderType;
import com.koron.order.common.bean.dto.OrderDispatchDto;
import com.koron.order.common.bean.vo.OrderDispatchVo;
import com.koron.order.common.service.OrderDispatchInfoService;
import com.koron.order.common.tools.CommonCodeTools;
import com.koron.order.common.tools.OrderCodeEnum;
import com.koron.order.defect.bean.convertor.DefectConvertor;
import com.koron.order.defect.bean.vo.DispatchVO;
import com.koron.order.defect.service.DefectService;
import com.koron.order.defect.service.DispatchService;
import com.koron.order.overhaul.bean.vo.OrderDispatchVO;
import com.koron.order.overhaul.service.OverhaulOrderService;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.List;

/**
 * (OrderChange)表服务实现类
 *
 * @author zhouj
 * @since 2022-02-16 18:14:27
 */
@Service("orderChangeService")
public class OrderChangeServiceImpl implements OrderChangeService {

    @Autowired
    OrderChangeConvertor orderChangeConvertor;

    @Autowired
    DefectConvertor defectConvertor;

    @Autowired
    OrderDispatchInfoService dispatchInfoService;

    @Autowired
    DispatchService defectDispatchService;

    @Autowired
    private OverhaulOrderService overhaulOrderService;

    @Autowired
    private DefectService defectService;

    @Override
    @TaskAnnotation("insertOrUpdate")
    public OrderChangePo insertOrUpdate(SessionFactory factory, OrderChangeDto orderChangeDto) {

        OrderChangeMapper mapper = factory.getMapper(OrderChangeMapper.class);

        OrderChangePo orderChangePo = orderChangeConvertor.dtoToPo(orderChangeDto);

        if (StringUtils.isEmpty(orderChangePo.getId())) {
            orderChangePo.setId(CodeTools.getCode32());
            orderChangePo.setCode(CommonCodeTools.getNormalOrderCode(orderChangePo.getOrderCode(), OrderCodeEnum.BG, 3));
            orderChangePo.setStatus(OrderChangeStatus.DRAFT.getStatus());
        } else {
            orderChangePo.setUpdateBy(null);
            orderChangePo.setUpdateByName(null);
            orderChangePo.setUpdateTime(null);
        }

        String orderType = orderChangePo.getOrderType();
        String orderId = orderChangePo.getOrderId();
        String changeOrderId = orderChangePo.getId();

        /*
         *草稿(不提交) 新增保存--根据工单类型调用不同接口
         * 点击(提交) 前端携带变更后的完整数据,首先需要将原来工单的全部数据复制一份到变更记录表
         * 再将前端携带的全部变更数据,录入到原工单表(即调用的是派工的新增保存)
         * */

        //存下来一个标志,线程可见,目的为了通知后面,使用变更表的mapper ThreadLocalOrderChange.set(OrderType.CHANGE);

        if (orderChangeDto.getIsCommit()) {
            //提交 先修改变更工单状态
            orderChangePo.setStatus(OrderChangeStatus.DONE.getStatus());

            //需要先保存变更前的数据

            if (StringUtils.equalsAnyIgnoreCase(orderType, OrderType.MAINTAIN, OrderType.REPAIR, OrderType.EXPERIMENT)) {
                //维护+计划性检修+试验工单

                //先保存变更前的数据 先查询出来原来数据,再入库到变更表
                OrderDispatchVo orderDispatchVo_pre = dispatchInfoService.queryByOrderId(factory, orderChangePo.getOrderId());
                OrderDispatchDto orderDispatchDto_pre = defectConvertor.voToDto(orderDispatchVo_pre);

                //设置变更标识,保存进变更表
                ThreadLocalOrderChange.set(OrderType.CHANGE);
                orderDispatchDto_pre.setOrderId(changeOrderId);
                dispatchInfoService.insertOrUpdate(factory, orderDispatchDto_pre);
                ThreadLocalOrderChange.clear();

                //保存前端数据到原来工单派工表
                OrderDispatchVo orderDispatchVo = orderChangeDto.getOrderDispatchVo();
                OrderDispatchDto orderDispatchDto = defectConvertor.voToDto(orderDispatchVo);
                orderDispatchDto.setOrderId(orderId);
                dispatchInfoService.insertOrUpdate(factory, orderDispatchDto);
            } else if (StringUtils.equalsAnyIgnoreCase(orderType, OrderType.DEFECT)) {
                //缺陷
                //先保存变更前的数据 先查询出来原来数据,再入库到变更表
                DispatchVO dispatchVO_query = new DispatchVO();
                dispatchVO_query.setOrderId(orderId);
                DispatchVO dispatchVO_pre = defectDispatchService.querySingle(factory, dispatchVO_query);

                //设置变更标识,保存进变更表
                ThreadLocalOrderChange.set(OrderType.CHANGE);
                dispatchVO_pre.setOrderId(changeOrderId);
                defectDispatchService.saveDispatch(factory, dispatchVO_pre);
                ThreadLocalOrderChange.clear();

                //保存前端数据到原来工单派工表
                DispatchVO defectDispatchVo = orderChangeDto.getDefectDispatchVo();
                defectDispatchVo.setOrderId(orderId);
                defectDispatchService.saveDispatch(factory, defectDispatchVo);



            } else if (StringUtils.equalsAnyIgnoreCase(orderType, OrderType.OVERHAUL)) {
                //大修
                //先保存变更前的数据 先查询出来原来数据,再入库到变更表
                OrderDispatchVO orderDispatchVO_pre = overhaulOrderService.queryDispatchInfoByOrderId(factory, orderId);

                //设置变更标识,保存进变更表
                ThreadLocalOrderChange.set(OrderType.CHANGE);
                orderDispatchVO_pre.setOrderId(changeOrderId);
                overhaulOrderService.dispatch(factory, orderDispatchVO_pre);
                ThreadLocalOrderChange.clear();

                //保存前端数据到原来工单派工表
                OrderDispatchVO overhaulDispatchVo = orderChangeDto.getOverhaulDispatchVo();
                overhaulDispatchVo.setOrderId(orderId);
                overhaulOrderService.dispatch(factory, overhaulDispatchVo);
            }

            //保存前端数据到原来的工单基本信息
            if (StringUtils.isNotEmpty(orderType) && StringUtils.isNotEmpty(orderChangePo.getNewMajor())){
                List<String> tableList = Arrays.asList("maintain","repair","experiment","defect","overhaul");
                if (tableList.contains(orderType)){
                    String prefix = "w_";
                    String suffix = orderType;
                    String tableName = prefix.concat(suffix);
                    String major = orderChangePo.getNewMajor();
                    mapper.updateBaseOrderMajor(tableName,orderId,major);
                }
            }
        } else {
            //1.非提交 仅仅只是保存草稿--即前端数据只保存在变更表

            if (StringUtils.equalsAnyIgnoreCase(orderType, OrderType.MAINTAIN, OrderType.REPAIR, OrderType.EXPERIMENT)) {
                //维护+计划性检修+试验工单

                //保存前端数据到工单变更表
                OrderDispatchVo orderDispatchVo = orderChangeDto.getOrderDispatchVo();
                OrderDispatchDto orderDispatchDto = defectConvertor.voToDto(orderDispatchVo);

                //设置变更标识,保存进变更表
                ThreadLocalOrderChange.set(OrderType.CHANGE);
                orderDispatchDto.setOrderId(changeOrderId);
                dispatchInfoService.insertOrUpdate(factory, orderDispatchDto);
                ThreadLocalOrderChange.clear();

            } else if (StringUtils.equalsAnyIgnoreCase(orderType, OrderType.DEFECT)) {
                //缺陷
                //保存前端数据到工单变更表
                DispatchVO defectDispatchVo = orderChangeDto.getDefectDispatchVo();

                //设置变更标识,保存进变更表
                ThreadLocalOrderChange.set(OrderType.CHANGE);
                defectDispatchVo.setOrderId(changeOrderId);
                defectDispatchService.saveDispatch(factory, defectDispatchVo);
                ThreadLocalOrderChange.clear();

            } else if (StringUtils.equalsAnyIgnoreCase(orderType, OrderType.OVERHAUL)) {
                //大修
                //保存前端数据到工单变更表
                OrderDispatchVO overhaulDispatchVo = orderChangeDto.getOverhaulDispatchVo();

                //设置变更标识,保存进变更表
                ThreadLocalOrderChange.set(OrderType.CHANGE);
                overhaulDispatchVo.setOrderId(changeOrderId);
                overhaulOrderService.dispatch(factory, overhaulDispatchVo);
                ThreadLocalOrderChange.clear();

            }

        }
        /*对变更工单进行保存时,先将变更的几张表数据全部删掉 再替换其中的工单id,再执行入库数据,
        当出现对同一个工单进行变更时,变更表应该保存的是多条,此时不能再使用id作为主键,应在表上新建字段作为主键*/

        //在这里存下来一个标志,线程可见,目的为了通知后面,使用变更表的mapper

        mapper.insertOrUpdate(orderChangePo);
        return orderChangePo;

    }

    @Override
    @TaskAnnotation("insertOrUpdateBatch")
    public int insertOrUpdateBatch(SessionFactory factory, List<OrderChangePo> orderChangeList) {

        OrderChangeMapper mapper = factory.getMapper(OrderChangeMapper.class);

        return mapper.insertOrUpdateBatch(orderChangeList);
    }

    @Override
    @TaskAnnotation("insert")
    public int insert(SessionFactory factory, OrderChangePo orderChange) {

        OrderChangeMapper mapper = factory.getMapper(OrderChangeMapper.class);

        return mapper.insert(orderChange);
    }

    @Override
    @TaskAnnotation("insertBatch")
    public int insertBatch(SessionFactory factory, List<OrderChangePo> orderChangeList) {

        OrderChangeMapper mapper = factory.getMapper(OrderChangeMapper.class);

        return mapper.insertBatch(orderChangeList);
    }

    @Override
    @TaskAnnotation("update")
    public int update(SessionFactory factory, OrderChangePo orderChange) {
        OrderChangeMapper mapper = factory.getMapper(OrderChangeMapper.class);
        return mapper.update(orderChange);
    }

    @Override
    @TaskAnnotation("deleteById")
    public int deleteById(SessionFactory factory, String id) {

        OrderChangeMapper mapper = factory.getMapper(OrderChangeMapper.class);
        return mapper.deleteById(id);
    }

    @Override
    @TaskAnnotation("queryById")
    public OrderChangeDetailVo queryById(SessionFactory factory, String id) {

        OrderChangeMapper mapper = factory.getMapper(OrderChangeMapper.class);

        //分别查询出工单的派工信息 新建时,此处应为空,保存后(草稿状态)再查询从变更处查询信息;
        OrderChangeVo orderChangeVo = mapper.queryById(id);
        String orderType = orderChangeVo.getOrderType();

        Assert.isTrue(orderChangeVo != null, "变更工单不能为空");
        Assert.isTrue(StringUtils.isNotEmpty(orderType), "工单状态不能为空");

        OrderChangeDetailVo orderChangeDetailVo = orderChangeConvertor.voToDetailVo(orderChangeVo);

        ThreadLocalOrderChange.set(OrderType.CHANGE);
        if (StringUtils.equalsAnyIgnoreCase(orderType, OrderType.MAINTAIN, OrderType.REPAIR, OrderType.EXPERIMENT)) {
            //维护+计划性检修+试验工单
            OrderDispatchVo orderDispatchVo = dispatchInfoService.queryByOrderId(factory, id);
            orderChangeDetailVo.setOrderDispatchVo(orderDispatchVo);
        } else if (StringUtils.equalsAnyIgnoreCase(orderType, OrderType.DEFECT)) {
            //缺陷
            DispatchVO dispatchVO = new DispatchVO();
            dispatchVO.setOrderId(id);
            DispatchVO defectDispatchVO = defectDispatchService.querySingle(factory, dispatchVO);
            orderChangeDetailVo.setDefectDispatchVo(defectDispatchVO);
        } else if (StringUtils.equalsAnyIgnoreCase(orderType, OrderType.OVERHAUL)) {
            //大修
            OrderDispatchVO orderDispatchVO = overhaulOrderService.queryDispatchInfoByOrderId(factory, id);
            orderChangeDetailVo.setOverhaulDispatchVo(orderDispatchVO);
        }
        ThreadLocalOrderChange.clear();

        return orderChangeDetailVo;
    }

    @Override
    @TaskAnnotation("queryList")
    public List<OrderChangeVo> queryList(SessionFactory factory, OrderChangeQuery query) {

        OrderChangeMapper mapper = factory.getMapper(OrderChangeMapper.class);

        List<OrderChangeVo> list = mapper.queryList(query);

        return list;
    }

    @Override
    @TaskAnnotation("queryPageList")
    public PageInfo queryPageList(SessionFactory factory, OrderChangeQuery query, PageQuery pageQuery) {

        PageHelper.startPage(pageQuery.getPage(), pageQuery.getPageSize(), pageQuery.getOrderBy(false));
        OrderChangeMapper mapper = factory.getMapper(OrderChangeMapper.class);

        List<OrderChangeVo> list = mapper.queryList(query);

        return new PageInfo(list);
    }

}
